package com.fyz.aaronfjava.util;

import org.assertj.core.util.Arrays;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @author AaronF
 * 字符串工具类
 * 提供了简单的字符串处理、拼接、判断等操作
 */
public class StringUtil {

    /**
     * 空白字符串
     */
    public static final String BLANK = "";

    /**
     * 判断字符串是否为空
     * 注意：如果传进来的字符串全为空格也会判定为空
     *
     * @param str 需要判断的字符串
     * @return true即为空 false即不为空
     */
    public static boolean isBlank(String str) {
        return str == null || str.trim().isEmpty();
    }

    /**
     * 判断字符串是否不为空
     * 注意：如果传进来的字符串全为空格也会判定为空
     *
     * @param str 需要判断的字符串
     * @return true即为不为空 false即为空
     */
    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    /**
     * 判断是否存在空字符串
     * @param arr 字符串数组
     * @return true即存在为空 false即都不为空
     */
    public static boolean isAnyBlank(String ... arr){
        if (Arrays.isNullOrEmpty(arr)){
            return true;
        }
        for (String s : arr) {
            if (isBlank(s)){
                return true;
            }
        }
        return false;
    }

    /**
     * 判断字符串是否存在于数组中 空字符串直接判断为不存在
     * @param str 字符串
     * @param arr 字符数组
     * @return
     */
    public static boolean contain(String str,String ... arr){
        if (Arrays.isNullOrEmpty(arr) || isBlank(str)){
            return false;
        }
        for (String s : arr) {
            if (s.equals(str)){
                return true;
            }
        }
        return false;
    }

    /**
     * 将对象属性转为get请求参数
     *
     * @param object
     * @return
     */
    public static String buildGetRequestStr(Object object) {
        if (object == null) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        // 如果是map则拼接键值对
        if (object instanceof Map) {
            ((Map) object).forEach((k, v) -> {
                if (k != null && v != null) {
                    sb.append(k).append("=").append(v).append("&");
                }
            });
            return sb.substring(0, Math.max(sb.length() - 1, 0));
        }
        // 反射获取对象属性
        Field[] fields = object.getClass().getDeclaredFields();
        try {
            for (Field field : fields) {
                field.setAccessible(true);
                Object value = field.get(object);
                if (value == null) continue;
                sb.append(field.getName()).append("=").append(value).append("&");
            }
        }catch (IllegalAccessException e){
            e.printStackTrace();
        }
        return sb.substring(0, Math.max(sb.length() - 1, 0));
    }

    /**
     * 将字符串集合整合成一个字符串
     *
     * @param list      字符串集合
     * @param delimiter 分隔符 允许为空
     * @return 如果集合为空 则返回空字符串
     */
    public static String listToString(List<String> list, String delimiter) {
        //判断集合是否为空
        if (list == null || list.isEmpty()) {
            return BLANK;
        }
        //如果分隔符为null则使用,代替
        delimiter = Objects.isNull(delimiter) ? "," : delimiter;
        StringBuilder sb = new StringBuilder();
        for (String str : list) {
            sb.append(str).append(delimiter);
        }
        //删除多余的分隔符
        return sb.substring(0,Math.max(sb.length() - delimiter.length(), 0));
    }
    /**
     * 判断字符串是否对称
     *
     * @param str 需要判断的字符串
     * @return true即对称 false即不对称
     */
    public static boolean isSymmetrical(String str) {
        return new StringBuffer(str).reverse().toString().equals(str);
    }

    /**
     * 替换字符串操作
     * 将源字符串两个索引之间的子字符串替换成目标字符串
     *
     * @param srcStr    原字符串
     * @param preIndex  替换位置前下标
     * @param lastIndex 替换位置后下标
     * @param tarStr    替换的字符串
     * @return 替换后的新字符串 如果输入非法返回空字符串
     */
    public static String replaceString(String srcStr, int preIndex, int lastIndex, String tarStr) {
        if (preIndex < 0 || lastIndex > srcStr.length() - 1 || lastIndex < preIndex) {
            return "";
        }
        //源字符串字符数组
        char[] srcChars = srcStr.toCharArray();
        //新字符串的长度
        int newCharsLength = srcChars.length + tarStr.length() - (lastIndex - preIndex + 1);
        //新字符串数组
        char[] tarChars = new char[newCharsLength];
        //指向数组当前赋值位置的指针
        int index = 0;
        //给新字符数组赋值
        //替换部分前半段
        for (int i = 0; i < preIndex; i++) {
            tarChars[index++] = srcChars[i];
        }
        //插入替换的部分
        for (int i = 0; i < tarStr.length(); i++) {
            tarChars[index++] = tarStr.charAt(i);
        }
        //替换部分后半段
        for (int i = lastIndex + 1; i < srcChars.length; i++) {
            tarChars[index++] = srcChars[i];
        }
        return new String(tarChars);
    }


}
